#Requires AutoHotkey v2.0
#Include SimLog.ahk
; #SingleInstance Force ; 单例
; #NoTrayIcon ; 不显示托盘图标

; v1.12_bate

; ----- 热字符串管理器 -----
class Corin {

    ; 名字
    name := "[FD_HotStrings V1.12]"

    ; 日志对象
    log := SimLog()

    ; 热字符串对象集合(HotStrings)
    hs := Map()

    ; 用户热字符串对象集合(User HotStrings)
    userHs := Map()

    ; 构造函数
    __New() {
        this.log.logPath := Format("{1}\FD_HotStrings.Log", this.log.PATH_FD)
        this.log.info(Format("{1} 启动", this.name))
        this._def()

    }

    _def() {

        ; 设置热字符串的结束字符
        Hotstring("EndChars", " `n,")  ; `n 表示换行（回车），空格（Space），逗号（,）

        ; 添加常用热串(常用)
        ; this.hs["test"] := "this is a test [faintdream]"

        this.hs["nm"] := "牛马"
        this.hs["rq"] := (h) => NiCole.rq(h)
        this.hs["rq-"] := (h) => NiCole.rq1(h)
        this.hs["rq."] := (h) => NiCole.rq2(h)
        this.hs["rq/"] := (h) => NiCole.rq3(h)
        this.hs["sj"] := (h) => NiCole.time(h)
        this.hs["sj8"] := (h) => NiCole.sj8(h)
        this.hs["sj16"] := (h) => NiCole.sj16(h)
        this.hs["v18"] := (h) => NiCole.out("(2018版本)")
        this.hs["v20"] := (h) => NiCole.out("(2020版本)")

        ; 添加常用热串(faintdream)
        for key, Value in this.hs {
            Hotstring("::" . key, Value, true)

        }

        ; 添加常用热串(用户定义)
        for key, Value in this.userHs {
            Hotstring("::" . key, Value, true)

        }
    }


}

; ----- 常用函数 -----
class NiCole {
    
    ; 日志对象
    static log := SimLog(EnvGet("USERPROFILE") . "\faintdream\Log\FD_HotStrings.Log")

    ; 定义名字
    static name := "NiCole"

    ; 输出模式(send 击键,  clip 粘贴)
    static OutModel := "clip"

    static out(text) {
        switch this.OutModel {
            case "send":
                SendInput(text)
            case "clip":
                this._clip(text)
            default:
                this.OutModel := "send"
                this.out(text)

        }
    }

    ; 输出模式clip模式的具体实现
    static _clip(text) {
        
	; 预留的回调函数接口 >> before_NiCole__clip()
        try {
            before_NiCole__clip()
	    this.log.debug(Format("[{1}] _clip()执行before_NiCole__clip() 回调函数成功",this.name))
        } catch {
	    this.log.debug(Format("[{1}] _clip()执行before_NiCole__clip() 回调函数失败(程序仍会正常执行)",this.name))
        }
        
        A_Clipboard := ""
        Sleep(11) ; 等待剪贴板中出现文本
        A_Clipboard := text  ; 文本放入粘贴板
        ClipWait(2) ; 等待剪贴板中出现文本
        if A_Clipboard == text {
            Send("^v")  ; 仅在剪贴板内容正确时才粘贴
        } else {
            MsgBox "剪贴板内容未能成功更新。"
        }
    }

    ; **随机数**
    /**
     * 生成随机字符串
     *  参数: length 生成的字符串长度
     *  可选参数: range 字符取值范围
     *   C 字母 + 数字(默认)
     *   N 数字(Number);
     *   A 字母(Alphabet);
     *   U 大写字母(Upper)
     *   L 小写字母(Lower)
     *   String 自定义一个字符串
     *  可选参数: isStr
     *   1 视参数range为字符串
     *   0 视参数range视为标识(默认)
     * 返回:生成的字符串
     */
    static randCh(length, range := "C", isStr := 0) {

        ; 随机数的取值范围
        local chars := ""

        ; 参数2不为字符串(不合法)
        if (!(range is String)) {
            return ""
        }

        ; 将参数2视为标识时
        if (!isStr) {
            range := StrReplace(range, "C", "NUL")
            range := StrReplace(range, "A", "UL")

            local num := "1234567890"
            local upper := "abcdefghijklmnopqrstuvwxyz"
            local lower := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

            loop Parse range {
                switch (A_LoopField) {

                    case "N":
                        chars .= num
                        num := ""
                        continue

                    case "U":
                        chars .= upper
                        upper := ""
                        continue

                    case "L":
                        chars .= lower
                        lower := ""
                        continue

                    default:
                        continue
                }
            }
        } else {
            chars := range
        }


        ; 字符数组长度不合法，返回空串
        if (length <= 0) {
            return ""
        }


        Loop length {
            randomIndex := Random(1, StrLen(chars))
            randomChar := SubStr(chars, randomIndex, 1)
            randomString .= randomChar
        }

        return randomString

    }

    static rq(h) {
        today := FormatTime("", "yyyyMMdd")
        this.out(today)
    }

    static rq1(h) {
        today := FormatTime("", "yyyy-MM-dd")
        this.out(today)
    }

    static rq2(h) {
        today := FormatTime("", "yyyy.MM.dd")
        this.out(today)
    }

    static rq3(h) {
        today := FormatTime("", "yyyy/MM/dd")
        this.out(today)
    }

    static time(h) {
        now := FormatTime("", "yyyy-MM-dd HH:mm:ss")
        this.out(now)
    }

    static sj8(h) {
        this.out(Nicole.randCh(8))
    }

    static sj16(h) {
        this.out(Nicole.randCh(16))
    }
}


; before_NiCole__clip